export type DateType =
    | 'year'
    | 'month'
    | 'week'
    | 'day'
    | 'year-month'
    | 'year-month-day'
    | 'month-day'
    | 'time';

export type WeekType = 'start' | 'end';

/**
 * 给定起止时间和间隔，返回时间段数组
 */
export function createTimeIntervals(opt: {
    /**
     * 开始时间
     */
    start: string;
    /**
     * 结束时间
     */
    end: string;
    /**
     * 间隔
     */
    interval?: number;
    /**
     * 开始时间是否大于当前时间
     */
    isStartGreaterThanNow?: boolean;
}): { label: string; value: string }[] {
    const result: Date[] = [];

    let startTime = new Date(`2024-01-01T${opt.start}`);
    const endTime = new Date(`2024-01-01T${opt.end}`);
    // 判断当前时间是否大于开始时间
    if (opt.isStartGreaterThanNow) {
        const nowDate = new Date();
        const nowTime = `${nowDate.getHours()}:00:00`;

        const now = new Date(`2024-01-01T${nowTime}`);

        if (now.getTime() > startTime.getTime()) {
            now.setHours(now.getHours() + 1);
            startTime = now;
        }

        if (now.getTime() > endTime.getTime()) {
            return [];
        }
    }

    const current = new Date(startTime.getTime());
    while (current < endTime) {
        result.push(new Date(current));
        current.setHours(current.getHours() + (opt?.interval || 1));
    }

    const padWithZero = (num: number) => {
        return ('0' + num).slice(-2);
    };

    return result.map((date) => {
        const e = new Date(date.getTime() + 3600000);
        const v = `${date.getHours()}:${padWithZero(
            date.getMinutes()
        )}-${e.getHours()}:${padWithZero(e.getMinutes())}`;
        return {
            label: v,
            value: v,
        };
    });
}

/**
 * 比较两个日期，返回lt小于 gt大于 eq等于
 * @param date1 日期1
 * @param date2 日期2
 * @description 时期格式：yyyy-MM-dd HH:mm:ss 或者 yyyy/MM/dd HH:mm:ss
 */
export function compareDate(date1: string, date2: string): 'lt' | 'gt' | 'eq' {
    if (date1.length === 10) {
        date1 = `${date1}T00:00:00`;
    } else if (date1.length === 8) {
        date1 = `2024-01-01T${date1}`;
    }
    if (date2.length === 10) {
        date2 = `${date2}T00:00:00`;
    } else if (date2.length === 8) {
        date2 = `2024-01-01T${date2}`;
    }

    const _date1 = new Date(date1);
    const _date2 = new Date(date2);

    if (_date1.getTime() > _date2.getTime()) {
        return 'gt';
    } else if (_date1.getTime() < _date2.getTime()) {
        return 'lt';
    }
    return 'eq';
}

/**
 * 获取指定月份天数
 * @param month 月份
 */
export function getMonthDays(month: string | Date): number {
    if (typeof month === 'string') {
        // 尝试将字符串转换为日期对象
        const date = new Date(month);

        // 检查日期对象是否有效
        if (isNaN(date.getTime())) {
            throw new Error('Invalid date string');
        }

        month = date;
    }

    if (month.getMonth() === 1) {
        if (isLeapYear(month.getFullYear())) {
            return 29;
        } else {
            return 28;
        }
    }

    if ([1, 3, 5, 7, 8, 10, 12].includes(month.getMonth() + 1)) {
        return 31;
    } else {
        return 30;
    }
}

// 辅助函数：判断是否是闰年
function isLeapYear(year: number): boolean {
    return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
}

/**
 * 获取指定月的起止日期，默认本月
 */
export function getMonthRange(month?: string | Date | number) {
    if (!month) {
        month = new Date();
    }

    if (typeof month === 'string' || typeof month === 'number') {
        month = new Date(month);
    }

    const start = new Date(month.getFullYear(), month.getMonth(), 1);

    const end = new Date(
        month.getFullYear(),
        month.getMonth(),
        getMonthDays(month)
    );

    return {
        start: getYearMonthDay(start),
        end: getYearMonthDay(end),
    };
}

/**
 * 获取日期所在周的起止日期
 */
export function getWeekRange(day?: string | Date) {
    if (!day) {
        day = new Date();
    }

    if (typeof day === 'string') {
        day = new Date(day);
    }

    const start = new Date(
        day.getFullYear(),
        day.getMonth(),
        day.getDate() - day.getDay()
    );
    const end = new Date(
        day.getFullYear(),
        day.getMonth() + 1,
        day.getDate() + (6 - day.getDay())
    );

    return {
        start: getYearMonthDay(start),
        end: getYearMonthDay(end),
    };
}

/**
 * 解析日期
 * @param date 可被解析的日期格式，可选，默认为当前日期
 * @param type 返回的类型，可选：'year' | 'month' | 'week' | 'day' | 'year-month' | 'year-month-day' | 'month-day'，默认'year-month-day'
 * @param symbol 间隔符号，可选，默认没有符号
 * @param week 周的第一天或最后一天，可选 'start' | 'end'
 * @returns 返回解析后的格式
 */
export function formatDate(
    date?: any,
    type?: DateType,
    symbol?: string,
    week?: WeekType
) {
    // 格式化日期
    const temp: any = date ? new Date(date) : new Date();
    // 获取年月日
    const year = temp.getFullYear();
    const tm = temp.getMonth() + 1;
    const month = tm < 10 ? `0${tm}` : tm;
    const td = temp.getDate();
    const day = td < 10 ? `0${td}` : td;
    // 获取时分秒
    const thour = temp.getHours();
    const hour = thour < 10 ? `0${thour}` : thour;
    const tminutes = temp.getMinutes();
    const minutes = tminutes < 10 ? `0${tminutes}` : tminutes;
    const tseconds = temp.getSeconds();
    const seconds = tseconds < 10 ? `0${tseconds}` : tseconds;
    // 获取间隔符号
    const sym = symbol ? symbol : '';

    // 根据类型返回
    if (type === 'year') return `${year}`;
    if (type === 'month') return `${month}`;
    if (type === 'day') return `${day}`;
    if (type === 'year-month') return `${year}${sym}${month}`;
    if (type === 'month-day') return `${month}${sym}${day}`;
    if (type === 'week') {
        const _date: any = new Date(temp - (temp.getDay() - 1) * 86400000);
        const first = _date.getDate();
        const __date = new Date((_date / 1000 + 6 * 86400) * 1000);
        const last = __date.getDate();

        if (week === 'start') {
            const _year = _date.getFullYear();
            const _month =
                _date.getMonth() + 1 < 10
                    ? `0${_date.getMonth() + 1}`
                    : _date.getMonth() + 1;
            const _day = first < 10 ? `0${first}` : first;
            return `${_year}${sym}${_month}${sym}${_day}`;
        }
        if (week === 'end') {
            const _year = __date.getFullYear();
            const _month =
                __date.getMonth() + 1 < 10
                    ? `0${__date.getMonth() + 1}`
                    : __date.getMonth() + 1;
            const _day = last < 10 ? `0${last}` : last;
            return `${_year}${sym}${_month}${sym}${_day}`;
        }
    }
    if (type === 'time')
        return `${year}${sym}${month}${sym}${day} ${hour}:${minutes}:${seconds}`;

    return `${year}${sym}${month}${sym}${day}`;
}

function getYear(date?: any, symbol = '-') {
    return formatDate(date, 'year', symbol);
}

function getMonth(date?: any, symbol = '-') {
    return formatDate(date, 'month', symbol);
}

function getDay(date?: any, symbol = '-') {
    return formatDate(date, 'day', symbol);
}

function getYearMonth(date?: any, symbol = '-') {
    return formatDate(date, 'year-month', symbol);
}

function getMonthDay(date?: any, symbol = '-') {
    return formatDate(date, 'month-day', symbol);
}

function getYearMonthDay(date?: any, symbol = '-') {
    return formatDate(date, 'year-month-day', symbol);
}

function getWeekFirstDay(date?: any, symbol = '-') {
    return formatDate(date, 'week', symbol, 'start');
}

function getWeekLastDay(date?: any, symbol = '-') {
    return formatDate(date, 'week', symbol, 'end');
}

function getTime(date?: any, symbol = '-') {
    return formatDate(date, 'time', symbol);
}

export {
    getYear,
    getMonth,
    getDay,
    getYearMonth,
    getMonthDay,
    getYearMonthDay,
    getWeekFirstDay,
    getWeekLastDay,
    getTime,
};
